<?php
namespace app\index\controller;
use think\Controller;
use Redis;
//use think\cache\driver\Redis;
use think\Cache;
use think\View;
use think\Db;
use Swoole;
class Index extends Controller
{
	
	/**
	*
	*	php异步
	*
	*/
	function yibu(){
		
		$this->asyncExecute('http://www.mode_01.com/index.php/index/index/edit',['1'=>'haha']);
		echo 123456;
	}
	
	/**
	*
	*	修改数据库
	*/
	public function edit(){
		$n = '111';
		DB::name('data')->where('id',1)->update(['title'=>$n]);
		echo 'yes';
	}
	//@生生 2018/12/05 11:25:06
	/**
     * [asyncExecute PHP异步执行任务]
     * @param  string $url       执行任务的url地址
     * @param  array  $post_data 需要post提交的数据POST
     * @param  array  $cookie    cookie数据用于登录等的设置(此处内部调用，无需鉴权)
     * @return boole
     */
	 
    public function asyncExecute($url, $post_data = array()) {
        $method = "GET";
        $url_array = parse_url($url);
        $port = isset($url_array['port']) ? $url_array['port'] : 80;

        $fp = fsockopen($url_array['host'], $port, $errno, $errstr, 30);
        if (!$fp) {
            return FALSE;
        }
        $getPath = isset($url_array['path']) ? $url_array['path'] : '/';
        if (isset($url_array['query'])) {
            $getPath .= "?" . $url_array['query'];
        }
        if (!empty($post_data)) {
            $method = "POST";
        }
        $header = $method . " /" . $getPath;
        $header .= " HTTP/1.1\r\n";
        $header .= "Host: " . $url_array['host'] . "\r\n";

        $header .= "Connection: Close\r\n";
//        if (!empty($cookie)) {
//            $_cookie = strval(NULL);
//            foreach ($cookie as $k => $v) {
//                $_cookie .= $k . "=" . $v . "; ";
//            }
//            $cookie_str = "Cookie: " . base64_encode($_cookie) . " \r\n";
//            $header .= $cookie_str;
//        }
        if (!empty($post_data)) {
            $_post = strval(NULL);
            $atComma = '';
            foreach ($post_data as $k => $v) {
                $_post .= $atComma . $k . "=" . $v;
                $atComma = '&';
            }
            $post_str = "Content-Type: application/x-www-form-urlencoded\r\n";
            $post_str .= "Content-Length: " . strlen($_post) . "\r\n";
            $post_str .= "\r\n".$_post . "\r\n";
            $header .= $post_str;
        }
        $header .= "\r\n";
        $re = fwrite($fp, $header);
        fclose($fp);
        return $re;
    }
	
	
	
	
	/*
	* redis基础
	* 蒋子建
	*
	*/
    public function index()
    {	$i=0;
    	while ( $i<= 10) {
    		echo $i;
    		echo '<br>';
    		$i++;
    	}
		//官网demo
		// $server = new swoole_server("0.0.0.0", 9501);

		// $server->on('open', function (swoole_websocket_server $server, $request) {
		// 	echo "server: handshake success with fd{$request->fd}\n";//$request->fd 是客户端id
		// });

		// $server->on('message', function (swoole_websocket_server $server, $frame) {
		// 	echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
		// 	$server->push($frame->fd, "this is server");//$frame->fd 是客户端id，$frame->data是客户端发送的数据
		// 	//服务端向客户端发送数据是用 $server->push( '客户端id' ,  '内容')
		// });

		// $server->on('close', function ($ser, $fd) {
		// 	echo "client {$fd} closed\n";
		// });

		// $server->start();
		
		
	
		
		
		
		
		
		/*
        $redis =  new Redis();
        $redis->connect('127.0.0.1', 6379);
		*/
		/*
		//reids的发布与订阅 pub/sub
		//test为发布的频道名称,hello,world为发布的消息
		$res = $redis->publish('test','hello,666');
		dump($res);die;
		*/
		
	
		
		
		/*
		$name = 'kuchun'; 
		$num  = 100;
		$len = $redis->llen($name);		//检查库存
		$count = $num-$len;				//实际内存-被抢库存=剩余库存
		for($i =0;$i<$count;$i++){
			$redis->lpush($name,1);
		}
		*/
		
		
		/*
		//抢购开始
		$user_id = input('id');
		$conut = $redis->lpop('kuchun');//lpop是移除并返回列表的第一个元素。
		if(!count){
			return '已经抢空';
		}
		
		$result = $redis->lpush('user',$user_id);
		if($result){
			return '恭喜您!抢到了哦';
		}
		　*/
		//DB::name('goods')->setDec('num');	//减少库存
		
	//高并发处理
	/*
		$redis->del('kuchun');	//清楚key保证是空
		$name = 'kuchun'; 
		$user = 10000;		//模拟10000人访问活动
		$num  = 100;		//成功人数
		$n = 0;				//数据量
		while($user--){
			$uid  = rand(10000,99999);
			$n++;
			$info = '第'.$n.'个成功者--'.$uid.'<br/>';
			if($redis->llen('kuchun')<$num){
				$redis->lpush($name,$info);
			}else{
				echo  $uid.'--'.'已经没有库存<br/>';
			}
		}
		dump($redis->lRange('kuchun',0,-1));
		die;
	*/	
		
	
	//------------------------------  redis中 Sorted-set(有序集合) 的操作
		/*
		$a6 = 	$redis -> zAdd('myset',1,'world');	//将一个或多个成员元素及其分数值加入到有序集当中。（分数值可以是整数值或双精度浮点数。
				$redis -> zAdd('myset',1,'foo');     
				$redis -> zAdd('myset',2,'hi');
				$redis -> zAdd('myset',2.5,'welcome');
		$b6 =   $redis->zRem('myset','hi');			//移除有序集中的一个或多个成员，不存在的成员将被忽略。
		$c6 = 	$redis ->zCard('myset');			//计算集合中的数量
		$d6 =   $redis->zCount('myset',1,3);		//用于计算有序集合中指定分数区间的成员数量。
		$e6 =   $redis->zScore('myset','foo');		//返回有序集中，成员的分数值。
		$f6 =   $redis->zIncrBy('myset',0.6,'world');//对有序集合中指定成员的分数加上增量 increment（分数值可以是整数值或双精度浮点数。）
		$g6 = 	$redis->zRange('myset',0,-1,'withScore');//返回有序集中，指定区间内的成员
		$h6 = 	$redis->zRevRange('myset',0,-1,'withScore');//除了成员按分数值递减的次序排列这一点外其他方面和 ZRANGE 命令一样。
		$i6 =	$redis->zRangeByScore('myset',2,3);	//用于移除有序集中，指定分数（score）区间内的所有成员。
		$j6 = 	$redis->zRemRangeByScore('myset',1,3);//用于移除有序集中指定分数（score）区间内的所有成员
				$array_set = array('myset','otherset');
		$k6 = 	$redis->zInter('destinationset',$array_set);//计算给定的一个或多个有序集的交集;返回值：保存到目标结果集的的成员数量。
		$l6 = 	$redis->zUnion('destinationset',$array_set);//计算给定的一个或多个有序集的并集.其作用与 redis 在 cmd 中ZUNIONSTORE 相同
		$m6 = 	$redis->zRank('myset','welcome');			//返回有序集中指定成员的排名
		$n6 = 	$redis->zRevRank('myset','welcome');		//回有序集中成员的排名。其中有序集成员按分数值递减(从大到小)排序
		$o6 = 	$redis->zRemRangeByRank('myset',1,3);		//移除有序集中指定排名(rank)区间内的所有成员。
		
		
		
		
		
		
//------------------------------  redis中 set 的操作
	/*
		$a5 = $redis->sAdd('myset','hello');		//令将一个或多个成员元素加入到集合中，已经存在于集合的成员元素将被忽略。
			  $redis->sAdd('myset','foo');		
			  $redis->sAdd('otherset','good');		
		$c5 = $redis->sRem('myset','hello','foo');	//移除集合中的一个或多个成员元素，不存在的成员元素会被忽略。
		$d5 = $redis->sMembers('myset');			//返回集合中的所有的成员。 不存在的集合 key 被视为空集合
		$e5 = $redis->sCard('myset');				//返回集合中元素的数量。
		$f5 = $redis->sMove('myset','destinationSet','foo')  //将指定成员 member 元素从 source 集合移动到 destination 集合。
		$g5 = $redis->spop('myset');				//用于移除并返回集合中的一个随机元素。
		$h5 = $redis->sRandMember('myset',3);		//返回集合中的一个随机元素,接受可选的 count 参数：
		$i5 = $redis->sInter('myset','otherset');	//返回给定所有给定集合的交集。 不存在的集合 key 被视为空集
		$j5 = $redis->sInterStore('destinationset','myset','otherset');//将给定集合之间的交集存储在指定的集合中。如果指定的集合已经存在，则将其覆盖
		$k5 = $redis->sUnion('myset','otherset');	//返回给定集合的并集。
		$l5 = $redis->sUnionStore('destinationset','myset','otherset');//将给定集合的并集存储在指定的集合 destination 中
		$m5 = $redis->sDiff('myset','otherset');	//返回给定集合之间的差集
		$n5 = $redis->sDiffStore('destinationset','myset','otherset'); //将给定集合之间的差集存储在指定的集合中
		$o5 = $redis->sIsMember('myset','hello');	//判断成员元素是否是集合的成员。
	*/




//------------------------------  redis中 list 的操作
/*
        $a4 = $redis->lpush('name','123');		//将一个或多个值插入到列表头部。
        $b4 = $redis->lpushx('name','apple');   //将一个或多个值插入到已存在的列表头部，列表不存在时操作无效。
        $c4 = $redis->rpush('name','456');		//将一个或多个值插入到列表的尾部(最右边)
		$d4 = $redis->rPushx('name','789');		//将一个或多个值插入到列表的尾部(最右边)如果列表不存在，操作无效
        $e4 = $redis->lpop('name');				//移除并返回列表的第一个元素。
        $f4 = $redis->rpop('name');				//用于移除并返回列表的最后一个元素。	
        $g4 = $redis->blpop('name',3);			//移出并获取列表的第一个元素 阻塞链接， 3s 之后超时结束
        $h4 = $redis->brpop('name',3);			//移出并获取列表的最后一个元素， 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
        $i4 = $redis->llen('name');				//返回列表的长度
        $j4 = $redis->lrange('name'0,-1);		//回列表中指定区间内的元素1 表示列表的第二个元素,以-1列表的最后一个元素,-2列表的倒数第二个元素
        $k4 = $redis->lrem('array','ooo',2);	//据参数 COUNT 的值，移除列表中与参数 VALUE 相等的元素。从开头向结尾方向移除 2 个
        $l4 = $redis->lset('name',1,'pineapple');//将第一个元素替换为 pineapple
		$m4 = $redis->ltrim('name',1,-1);		//对一个列表进行修剪(trim),只保留指定区间内的元素，不在区间之内元素都将被删除
		$n4 = $redis->lindex('name',2);			//用于通过索引获取列表中的元素
		$o4 = $redis->lInsert('name','before','apple','Mango');//在列表的元素前或者后插入元素
		$p4 = $redis->rpoplpush('name','name');	//移除列表的最后一个元素，并将该元素添加到另一个列表并返回
		$q4 = $redis->brpoplpush('name','name',2); //从列表中弹出一个值，将弹出的元素插入到另外一个列表中并返回它；
*/
		
		
		
		
		
		
		
		
		
		
		
		
		

//------------------------------  redis中 hash 的操作
	/*
        $a3 = $redis->hSet('myhash','name','cherry');   //用于为哈希表中的字段赋值 。
        $b3 = $redis->hget('name');   				    //返回哈希表中指定字段的值
        $c3 = $redis->hsetnx('myhash','name1','cherry');//为哈希表中不存在的的字段赋值 如果字段已经存在于哈希表中，操作无效。
		$array_hmset = array(
			'pats' => 'dog',
			'fruit' => 'cherry',
			'job' => 'programmer'
		);
		$d3 = $redis->hMset('myhash',$array_hmset);		//同时将多个 field-value (字段-值)对设置到哈希表中。
        $e3 = $redis->hMGet('myhash',$array_hmget)		//返回哈希表中，一个或多个给定字段的值。
        $f3 = $reids->hGetAll('myhash');  				//返回哈希表中，所有的字段和值
        $g3 = $redis->hdel('myhash','name');      		//用于删除哈希表 key 中的一个或多个指定字段，不存在的字段将被忽略。
        $h3 = $redis->hlen('myhash');      				//用于获取哈希表中字段的数量。
        $i3 = $redis->hExists('myhash','name1'); 		//查看哈希表的指定字段是否存在。
        $j3 = $redis->hIncrBy('myhash','name1',5);		//为哈希表中的字段值加上指定增量值。增量也可以为负数，相当于对指定字段进行减法操作。
        $k3 = $redis->hIncrByFloat('myhash','name1',0.3); //为哈希表中的字段值加上指定浮点数增量值。
        $l3 = $redis->hKeys('myhash');    				//获取哈希表中的所有字段名	
		$m3 = $redis->hVals('myhash');    				//返回哈希表所有字段的值。			
	*/
		
		
		
		
		
		
		
		
		
//------------------------------  redis中 key 的操作
//        $a2 = $redis->del('name');      //用于删除已存在的键。不存在的 key 会被忽略。
//        $b2 = $redis->exists('name');   //检查给定 key 是否存在。
//        $c2 = $redis->expire('name',30);//设置 key 的过期时间。key 过期后将不再可用
//        $d2 = $redis->expireat('name',time()+10); //以 UNIX 时间戳(unix timestamp)格式设置 key 的过期时间。key 过期后将不再可用。
//        $e2 = $redis->keys('*');        //查找所有符合给定模式 pattern 的 key
//        $f2 = $reids->persist('name');  //移除给定 key 的过期时间，使得 key 永不过期。
//        $g2 = $redis->TTL('name');      //以秒为单位返回 key 的剩余过期时间。
//        $h2 = $redis->randomKey();      //从当前数据库中随机返回一个 key (不删除) 。
//        $i2 = $redis->rename('name','newname'); //用于修改 key 的名称 。
//        $j2 = $redis->renameNx('name','noname');//用于在新的 key 不存在时修改 key 的名称 。返回 key 所储存的值的类型。
//        $k2 = $redis->type('name');    //返回 key 所储存的值的类型。
//        $l2 = $redis->sort('name');    //返回 key 所储存的值的类型






//------------------------------  redis中 string 的操作
//		$a1 = $redis->set('name','123456789');	//设置指定 key 的值
//		$b1 = $redis->get('name'); 				//通过key获取字符串值
//		$c1 = $redis->getrange('name',0,-1);		//返回 key 中字符串值的子字符
//		$d1 = $redis->getSet('name','87654321');	//设置指定 key 的值，并返回 key 旧的值,当 key 没有旧值时，返回 nil 。当 key 存在但不是字符串类型时，返回一个错误
//        $e1 = $redis->setnx('key',555);            //在指定的 key 不存在时，为 key 设置指定的值
//        $f1 = $redis->setex('job',20,'覆盖');     //为指定的 key 设置值及其过期时间。如果 key 已经存在， SETEX 命令将会替换旧的值
//        $g1 = $redis->setbit('name',0,1);			//kkey所储存的字符串值，设置或清除指定偏移量上的位(bit)。
//		$h1 = $redis->getbit('name',7);			//对key所储存的字符串值，获取指定偏移量上的位(bit)。
//        $i1 = $redis->setrange('name',2,'redis');	//用指定的字符串覆盖给定 key 所储存的字符串值，覆盖的位置从偏移量 offset 开始。
//        $array_mset = array(
//            'year' => 2017,
//            'month' => 5,
//            'date' => 10,
//            'time' => '11:04'
//        );
//        $j1 = $redis->mset($array_mset);         //同时设置一个或多个 key-value 对。
//        $k1 = $redis->msetnx($array_mset);       //所有给定 key 都不存在时，同时设置一个或多个 key-value 对,即使只有一个key已存在，会拒绝所有操作
//        $l1 = $redis->append('job','PHPer');   //为指定的 key 追之追加到 key 原来的值的末尾，不存在就如set
//        $array_mget = array('year','month','fake_key');
//        $m1 = $redis->mget($array_mget);         //返回所有(一个或多个)给定 key 的值。 如果给定的 key 里面，有某个 key 不存在，那么这个 key 返回特殊值 nil 。
//        $n1 = $redis->strlen('job');            //获取指定 key 所储存的字符串值的长度。当 key 储存的不是字符串值时，返回一个错
//        $o1 = $redis->incr('name');             //将 key 中储存的数字值增一。如果 key 不存在，那么 key 的值会先被初始化为 0 ，然后再执行 INCR 操作
//        $p1 = $redis->incrby('name',5);         //将 key 中储存的数字加上指定的增量值
//        $q1 = $redis ->incrByFloat('name',0.3); //为 key 中所储存的值加上指定的浮点数增量值
//        $r1 = $redis ->decr('name');            //将 key 中储存的数字值减一
//        $s1 = $redis ->decrby('name',5);        //将 key 所储存的值减去指定的减量值。
		
		
		
		
		/*
        $name = 'miaosha';
        $num = '100';   //秒杀活动会有100人成功
        $i = 20000;      //模拟20000用户瞬间访问活动
        $n = 0;          //数据量
        while($i--){
            $n++;
            $uid = rand(1000000,99999999);
            if($redis->llen($name)<$num){
                $redis->rpush($name,$uid);
                echo $uid.'秒杀成功'.$n.'<br/>';
            }else{
                echo $uid.'秒杀结束无库存'.$n.'<br/>';
            }
       }
        dump($redis->lRange('miaosha',0,-1));
       $redis->close();
       die;
	   */
       //Cache::store('redis')->set('test','jianhahahahhaha  ');
       //echo Cache::get('test');
        //cache('name','888');
        // echo cache('name');
        //phpinfo();die;
        //var_dump($redis -> lPush('favorite_fruit2','cherry'));     // key 不存在，创建一个新的列表, 返回 int 1
        // var_dump($redis -> lPush('favorite_fruit2','banana'));     // key 存在。但是 list 类型, 返回 int 2
        //$redis -> set('pats','dog');
        //var_dump($redis -> lPush('pats','cat'));     // key 存在。但不是是 list 类型, 返回 boolean false
        // var_dump($redis->lRange('pats',0,-1));var_dump($redis -> rPush('favorite_fruit','cherry'));
        //var_dump($redis -> rPush('favorite_fruit1','999'));
        //var_dump($redis -> lPushx('favorite_fruit1','apple'));     //  返回 int 3
        //var_dump($redis -> rPop('favorite_fruit1'));             // string apple
        //$redis -> hSet('myhash','favorite_fruit','cherry');
        //var_dump($redis -> hGet('myhash','favorite_fruit'));
        //var_dump($redis -> lRange('favorite_fruit1',0,-1));

        /*
        $array =
         [
            '0'=>['id'=>1],
            '1'=>['id'=>2]
        ];
        View::share('a',10);
        View::share('b',20);
        $this->assign('array',$array);
        return $this->fetch('index',['name'=>$name],['shop'=>'ooooo']);*/
        //return '<style type="text/css">*{ padding: 0; margin: 0; } .think_default_text{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: "Century Gothic","Microsoft yahei"; color: #333;font-size:18px} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style="padding: 24px 48px;"> <h1>:)</h1><p> ThinkPHP V5<br/><span style="font-size:30px">十年磨一剑 - 为API开发设计的高性能框架</span></p><span style="font-size:22px;">[ V5.0 版本由 <a href="http://www.qiniu.com" target="qiniu">七牛云</a> 独家赞助发布 ]</span></div><script type="text/javascript" src="https://tajs.qq.com/stats?sId=9347272" charset="UTF-8"></script><script type="text/javascript" src="https://e.topthink.com/Public/static/client.js"></script><think id="ad_bd568ce7058a1091"></think>';
    }
	
	//添加队列
	public function set(){
		$redis =  new Redis();
        $redis->connect('127.0.0.1', 6379);
		$key = input('key');
		$val = input('val');
		$res = $redis->lpush($key,$val);
		return dump($res);
	}
	//移除队列
	public function get(){
		$redis =  new Redis();
        $redis->connect('127.0.0.1', 6379);
		$key = input('key');
		$res = $redis->rpop($key);
		return dump($res);
	}
}
